package com.yixin.hospital.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.BusinessException;
import com.yixin.hospital.common.Constant;
import com.yixin.hospital.entity.bo.PageInfo;
import com.yixin.hospital.entity.domain.CheckDetail;
import com.yixin.hospital.entity.domain.CheckRepository;
import com.yixin.hospital.entity.domain.DrugDepositoryDrug;
import com.yixin.hospital.entity.dto.req.check.CheckAddReqDTO;
import com.yixin.hospital.entity.dto.req.check.WriteOffReqDTO;
import com.yixin.hospital.entity.vo.CheckDetailVo;
import com.yixin.hospital.entity.vo.CheckRepositoryVo;
import com.yixin.hospital.entity.vo.DrugDepositoryDrugVo;
import com.yixin.hospital.enums.CheckDetailStatusEnum;
import com.yixin.hospital.enums.DrugDepositoryOtpTypeEnum;
import com.yixin.hospital.enums.ResponseCodeEnum;
import com.yixin.hospital.mapper.extend.CheckRepositoryExtendMapper;
import com.yixin.hospital.mapper.extend.DrugDepositoryDrugExtendMapper;
import com.yixin.hospital.service.CheckDetailService;
import com.yixin.hospital.service.CheckRepositoryService;
import com.yixin.hospital.service.DrugDepositoryDrugService;
import com.yixin.hospital.service.DrugDepositoryService;
import com.yixin.hospital.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.temporal.ChronoUnit;
import java.util.*;

import static com.yixin.hospital.enums.ResponseCodeEnum.INVALID_CHECK;
import static com.yixin.hospital.enums.ResponseCodeEnum.INVALID_CHECK_NUM;

@RestController
@RequestMapping("/check-repository")
@Api(value = "盘点管理", tags = "盘点管理")
public class CheckRepositoryController {

    @Resource
    CheckRepositoryService checkService;
    @Resource
    CheckDetailService checkDetailService;
    @Resource
    CheckRepositoryService checkRepositoryService;
    @Resource
    CheckRepositoryExtendMapper checkRepositoryExtendMapper;
    @Resource
    DrugDepositoryService drugDepositoryService;
    @Resource
    DrugDepositoryAuthController drugDepositoryAuthController;
    @Resource
    DrugDepositoryDrugService drugDepositoryDrugService;
    @Resource
    private DrugDepositoryDrugExtendMapper drugDepositoryDrugExtendMapper;

    @GetMapping("/list")
    @ApiOperation(value = "盘点记录列表")
    public ApiResult<?> list(@RequestParam int currentPage, @RequestParam int pageSize, Long drugDepositoryId, HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
//        List<DrugDepository> list = drugDepositoryService.list(new LambdaQueryWrapper<DrugDepository>().eq(DrugDepository::getDept, deptId));
//        List<Long> depositoryIdsByDept = list.stream().map(DrugDepository::getId).collect(Collectors.toList());
//        List<Long> depositoryIdsByAuth = new ArrayList<>();
//        for (Long depositoryId : depositoryIdsByDept) {
//            if (drugDepositoryAuthController.checkDrugDepositoryAuth(userId, depositoryId, DrugDepositoryOtpTypeEnum.CHECK.getCode())) {
//                depositoryIdsByAuth.add(depositoryId);
//            }
//        }
        if (!drugDepositoryAuthController.checkDrugDepositoryAuth(userId, drugDepositoryId, DrugDepositoryOtpTypeEnum.CHECK.getCode())) {
            return ApiResult.error(ResponseCodeEnum.AUTH_NOT_FOUND);
        }
        IPage<CheckRepositoryVo> checkRepositoryVoIPage = checkRepositoryExtendMapper.pageVo(Page.of(currentPage, pageSize), Arrays.asList(drugDepositoryId), null);
        PageInfo<CheckRepositoryVo> checkRepositoryVoPageInfo = new PageInfo<>();
        BeanUtils.copyProperties(checkRepositoryVoIPage, checkRepositoryVoPageInfo);
        return ApiResult.success(checkRepositoryVoPageInfo);
    }

    @GetMapping("/info")
    @ApiOperation(value = "盘点详情")
    public ApiResult<?> info(@RequestParam int currentPage, @RequestParam int pageSize, @RequestParam int checkId) {
        LambdaQueryWrapper<CheckDetail> checkDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
        checkDetailLambdaQueryWrapper.eq(CheckDetail::getCheckId, checkId);
        Page<CheckDetail> page = checkDetailService.page(Page.of(currentPage, pageSize), checkDetailLambdaQueryWrapper);
        PageInfo<CheckDetailVo> pageInfo = new PageInfo<>();
        BeanUtils.copyProperties(page, pageInfo);
        return ApiResult.success(pageInfo);
    }

    @PostMapping("/addOrUpdate")
    @Transactional
    @ApiOperation(value = "添加盘点")
    public ApiResult<?> addOrUpdate(@Valid @RequestBody CheckAddReqDTO checkAddReqDTO, HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        if (Objects.equals(checkAddReqDTO.getStatus(), 1)) {    // 1 提交    0 草稿
            for (CheckAddReqDTO.CheckDetailAddReqDTO checkDetailAddReqDTO : checkAddReqDTO.getCheckDetailAddReqDTOList()) {
                if (Objects.isNull(checkDetailAddReqDTO.getCheckNum())) return ApiResult.error(INVALID_CHECK_NUM);
            }
        }
        CheckRepository check = new CheckRepository();
        check.setCheckDepositoryId(checkAddReqDTO.getCheckDepositoryId());
        check.setRemarks(checkAddReqDTO.getRemarks());
        check.setCheckUserId(userId);
        check.setStatus(checkAddReqDTO.getStatus());
        // 修改
        if (Objects.nonNull(checkAddReqDTO.getId())) {
            check.setId(checkAddReqDTO.getId());
            checkService.updateById(check);
        } else {
            //添加
            check.setCreatedBy(userName);
            checkService.save(check);
        }
        checkDetailService.remove(new LambdaQueryWrapper<CheckDetail>().like(CheckDetail::getCheckId, check.getId()));
        List<CheckDetail> checkDetailList = new ArrayList<>();
        for (CheckAddReqDTO.CheckDetailAddReqDTO checkDetailAddReqDTO : checkAddReqDTO.getCheckDetailAddReqDTOList()) {
            CheckDetail checkDetail = new CheckDetail();
            BeanUtil.copyProperties(checkDetailAddReqDTO, checkDetail, "id");
            checkDetail.setCreatedBy(userName);
            checkDetail.setCheckId(check.getId());
            checkDetail.setCheckNum(checkDetailAddReqDTO.getCheckNum());
            checkDetailList.add(checkDetail);
        }
        checkDetailService.saveBatch(checkDetailList);
        return ApiResult.success();
    }


    @GetMapping("/writeOffList")
    @ApiOperation(value = "核销记录列表")
    public ApiResult<?> writeOffList(@RequestParam int currentPage, @RequestParam int pageSize, Long drugDepositoryId, HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
//        List<DrugDepository> list = drugDepositoryService.list(new LambdaQueryWrapper<DrugDepository>().eq(DrugDepository::getDept, deptId));
//        List<Long> depositoryIdsByDept = list.stream().map(DrugDepository::getId).collect(Collectors.toList());
//        List<Long> depositoryIdsByAuth = new ArrayList<>();
//        for (Long depositoryId : depositoryIdsByDept) {
//            if (drugDepositoryAuthController.checkDrugDepositoryAuth(userId, depositoryId, DrugDepositoryOtpTypeEnum.CHECK.getCode())) {
//                depositoryIdsByAuth.add(depositoryId);
//            }
//        }
        if (!drugDepositoryAuthController.checkDrugDepositoryAuth(userId, drugDepositoryId, DrugDepositoryOtpTypeEnum.WRITE_OFF.getCode())) {
            return ApiResult.error(ResponseCodeEnum.AUTH_NOT_FOUND);
        }
        IPage<CheckRepositoryVo> checkRepositoryVoIPage = checkRepositoryExtendMapper.pageVo(Page.of(currentPage, pageSize), Arrays.asList(drugDepositoryId), Arrays.asList(1, 2));
        PageInfo<CheckRepositoryVo> checkRepositoryVoPageInfo = new PageInfo<>();
        BeanUtils.copyProperties(checkRepositoryVoIPage, checkRepositoryVoPageInfo);
        return ApiResult.success(checkRepositoryVoPageInfo);
    }

    @PostMapping("/writeOff")
    @Transactional
    @ApiOperation(value = "核销")
    public ApiResult<?> writeOff(@Valid @RequestBody WriteOffReqDTO writeOffReqDTO, HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        CheckDetail checkDetail = checkDetailService.getById(writeOffReqDTO.getCheckDetailId());
        CheckRepository checkRepository = checkRepositoryService.getById(checkDetail.getCheckId());
        if (checkRepository.getStatus().equals(CheckDetailStatusEnum.DRAFT.getCode())) {    // 1 提交    0 草稿
            return ApiResult.error(INVALID_CHECK);
        }
        checkDetail.setIsWriteOff(1);
        checkDetail.setWriteOffUserId(userId);
        checkDetail.setWriteOffUserName(userName);
        checkDetail.setWriteOffNum(writeOffReqDTO.getWriteOffNum());
        checkDetail.setSubWriteOffNum(writeOffReqDTO.getSubWriteOffNum());
        checkDetail.setWriteOffRemark(writeOffReqDTO.getWriteOffRemark());
        checkDetail.setUpdatedBy(userName);
        checkDetail.setUpdatedTime(new Date());
        checkDetailService.updateById(checkDetail);
        // 改库存
        DrugDepositoryDrug one = drugDepositoryDrugService.getOne(new LambdaQueryWrapper<DrugDepositoryDrug>()
                .eq(DrugDepositoryDrug::getDrugDepositoryId, checkRepository.getCheckDepositoryId())
                .eq(DrugDepositoryDrug::getDrugCode, checkDetail.getDrugCode())
                .eq(DrugDepositoryDrug::getProductTime, checkDetail.getProductTime())
                .eq(DrugDepositoryDrug::getExpiration, checkDetail.getExpiration()));

        one.setNum(checkDetail.getWriteOffNum());
        one.setSubNum(checkDetail.getSubWriteOffNum());
        one.setUpdatedBy(userName);
        one.setUpdatedTime(new Date());
        drugDepositoryDrugService.updateById(one);
        // 判断状态
        long count = checkDetailService.count(new LambdaQueryWrapper<CheckDetail>().eq(CheckDetail::getCheckId, checkDetail.getCheckId()).eq(CheckDetail::getIsWriteOff, 0));
        if (count == 0 && StringUtils.isNotBlank(checkRepository.getRemarks())) {
            checkRepository.setStatus(CheckDetailStatusEnum.WRITE_OFF.getCode());
            checkRepositoryService.updateById(checkRepository);
        }
        return ApiResult.success();
    }

    @PostMapping("/writeOff-remarks")
    @Transactional
    @ApiOperation(value = "核销单建议")
    public ApiResult<?> writeOffRemarks(@Valid @RequestBody WriteOffReqDTO writeOffReqDTO, HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        CheckRepository checkRepository = checkRepositoryService.getById(writeOffReqDTO.getCheckRepositoryId());
        checkRepository.setRemarks(writeOffReqDTO.getRemarks());
        checkRepository.setUpdatedBy(userName);
        checkRepository.setUpdatedTime(new Date());
        // 判断状态
        long count = checkDetailService.count(new LambdaQueryWrapper<CheckDetail>().eq(CheckDetail::getCheckId, writeOffReqDTO.getCheckRepositoryId()).eq(CheckDetail::getIsWriteOff, 0));
        if (count == 0 && StringUtils.isNotBlank(checkRepository.getRemarks())) {
            checkRepository.setStatus(CheckDetailStatusEnum.WRITE_OFF.getCode());
        }
        checkRepositoryService.updateById(checkRepository);
        return ApiResult.success();
    }

    @GetMapping("/depository-num-list")
    @ApiOperation(value = "根据药品Id 库房id 查库存列表")
    public ApiResult<?> queryDepositoryNumList(@RequestParam int currentPage, @RequestParam int pageSize,
                                               @RequestParam(value = "drugDepositoryId") Long drugDepositoryId, HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        if (!drugDepositoryAuthController.checkDrugDepositoryAuth(userId, drugDepositoryId, DrugDepositoryOtpTypeEnum.QUERY.getCode())) {
            return ApiResult.error(ResponseCodeEnum.AUTH_NOT_FOUND);
        }
        IPage<DrugDepositoryDrugVo> drugDepositoryDrugVoList = drugDepositoryDrugExtendMapper.DepositoryCountListPage(Page.of(currentPage, pageSize), Arrays.asList(drugDepositoryId), null, 1);
//        for (DrugDepositoryDrugVo record : drugDepositoryDrugVoList.getRecords()) {
//            long daysDiff = ChronoUnit.DAYS.between(record.getExpiration().toInstant(), new Date().toInstant());
//            if (daysDiff > drugNearExpiration) {
//                record.setNearExpiration(true);
//            }
//        }
        return ApiResult.success(drugDepositoryDrugVoList);
    }

}
